<html>
<head><meta charset="utf-8"><title>Erasing lifetime · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Erasing.20lifetime.html">Erasing lifetime</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="221800046"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Erasing%20lifetime/near/221800046" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Michał Muskała <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Erasing.20lifetime.html#221800046">(Jan 06 2021 at 18:00)</a>:</h4>
<p>Let's say I have two structs from a library - <code>Tree</code> and <code>Node&lt;'tree&gt;</code>, but I'd like to operate on something without the lifetime (primarily for storing it in other data structures). Would it be safe to have a wrapper struct defining something like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">WrapperNode</span><span class="p">(</span><span class="n">Rc</span><span class="o">&lt;</span><span class="n">Tree</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">Node</span><span class="o">&lt;'</span><span class="nb">static</span><span class="o">&gt;</span><span class="p">);</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">WrapperNode</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">(</span><span class="n">tree</span>: <span class="nc">Rc</span><span class="o">&lt;</span><span class="n">Tree</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">node</span>: <span class="nc">Node</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">WrapperNode</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">WrapperNode</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">mem</span>::<span class="n">transmute</span><span class="p">(</span><span class="n">node</span><span class="p">)</span><span class="w"> </span><span class="p">})</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>

<span class="w">  </span><span class="k">pub</span><span class="w">  </span><span class="k">fn</span> <span class="nf">node</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;'</span><span class="na">a</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Node</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">mem</span>::<span class="n">transmute</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>As far as I understand this should be safe, since on access to the node, the lifetime is restricted back to one that ensures the <code>Tree</code> lives longer than the <code>Node</code> itself, it shouldn't be possible for the <code>Node</code> to outlive <code>WrapperNode</code> and hence the <code>Tree</code> itself</p>



<a name="221800360"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Erasing%20lifetime/near/221800360" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Erasing.20lifetime.html#221800360">(Jan 06 2021 at 18:02)</a>:</h4>
<p>You are not ensuring that <code>Node&lt;'a&gt;</code> is part of the <code>Rc&lt;Tree&gt;</code> that is passed in.</p>



<a name="221801317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Erasing%20lifetime/near/221801317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Michał Muskała <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Erasing.20lifetime.html#221801317">(Jan 06 2021 at 18:10)</a>:</h4>
<p>Yeah, that's true. I couldn't really figure out how to do that. My understanding is that normally this could be achieved with <code>&amp;'tree Tree</code>, but this doesn't help if I have a <code>Rc</code> wrapper around it. </p>
<p>I'm not sure there's a way to ensure this, other than by construction, where the <code>new</code> wouldn't be public and only used internally with something like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">root_from_tree</span><span class="p">(</span><span class="n">tree</span>: <span class="nc">Tree</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">WrapperNode</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">new</span><span class="p">(</span><span class="n">Rc</span>::<span class="n">new</span><span class="p">(</span><span class="n">tree</span><span class="p">),</span><span class="w"> </span><span class="n">tree</span><span class="p">.</span><span class="n">root_node</span><span class="p">())</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">children</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">ChildrenIterator</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="c1">// internally the iterator uses `WrapperNode::new` making sure to pass in the parent tree</span>
<span class="w">  </span><span class="n">ChildrenIterator</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">clone</span><span class="p">())</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="221835451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Erasing%20lifetime/near/221835451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Erasing.20lifetime.html#221835451">(Jan 06 2021 at 23:00)</a>:</h4>
<p>This sounds like the <code>OwningHandle</code> API in <a href="https://crates.io/crates/owning_ref"><code>owning_ref</code></a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>